# Title     : TODO
# Objective : TODO
# Created by: xueyj
# Created on: 2020/9/29
#pacman::p_load(reshape2, magrittr, dplyr, lazyopt)
suppressMessages(library("reshape2"))

suppressMessages(library("lazyopt"))

suppressMessages(library("dplyr"))

suppressMessages(library("magrittr"))

suppressMessages(library("chron"))

#数据平滑前后各30个点
weightsmooth <- function(a, n = 30) {
  for (i in seq_along(a)) {
    if (i - n >= 1) {
      a[i] <- mean(a[(i - n):(i + n)], na.rm = TRUE)
    }else {
      a[i] <- mean(a[1:(i + n)], na.rm = TRUE)
    }
  }
  return(a)
}

get_unit <- function(rawData, choseUnit) {
  if (choseUnit %in%
    (colnames(rawData)[3:ncol(rawData)])) {
    return(rawData %>%
             select(c("Time", "Sensor",
                      choseUnit)) %>%
             dcast(Time ~ Sensor)
    )
  }else {
    return(-1)
  }
}

get_genotype <- function(rawData, choose_genotype,
                         genotypes, groupData, units) {
  if (choose_genotype %in%
    genotypes) {
    needc <- groupData[which(groupData[, 2] == choose_genotype), 1] %>%
      as.character()
    need <- NULL
    for (i in seq_along(needc)) {
      if (needc[i] %in%
        units) {
        need[length(need) + 1] <- needc[i]
      }
    }
    if (is.null(need)) { return(-1) }else {
      result <- rawData %>%
        select(c("Time", "Sensor", need))
      mean <- (result[3:ncol(result)]) %>%
        rowMeans(., na.rm = T) %>%
        as.numeric()
      result %<>% mutate(means = mean) %>%
        select(c("Time", "Sensor", "means")) %>%
        set_colnames(c("Time", "Sensor", choose_genotype)) %>%
        dcast(Time ~ Sensor) %>%
        return()
    }
  }else {
    return(-1)
  }
}

computed_vpd_vwc <- function(unitData) {
  if (unitData == -1) {
    return(-1)
  }else {
    vpd <- (1 - unitData[, 4] / 100) *
      0.6112 *
      exp((17.67 * unitData[, 6]) / (243.5 + unitData[, 6]))
    vwc <- 4.3 * (10^-6) * (unitData[, 3]^3) - 5.5 * (10^-4) *
      (unitData[, 3]^2) + 2.92 * (10^-2) * unitData[, 3] -
      5.3 * (10^-2)
    unitData %<>%
      mutate(vpd = vpd, vwc = vwc)
    unitData[is.na(unitData)] <- ""
    return(unitData)
  }
}


computed_Tr_bytype <- function(b, type) {
  #center,forward,Taylor
  type %<>% match.arg(c("center", "forward", "Taylor"))
  result <- c()
  b %<>% as.numeric() %>% weightsmooth()
  if (type == "Taylor") {
    for (z in seq_along(b)) {
      result[z] <- (8 * b[z + 1] - 8 * b[z - 1] - b[z + 2] + b[z - 2]) / (12 * 3)
    }
  }
  if (type == "center") {
    for (z in seq_along(b)) {
      result[z] <- (1 * b[z + 1] - 1 * b[z - 1]) / 2 / 3
    }
  }
  if (type == "forward") {
    for (z in seq_along(b)) {
      result[z] <- (1 * b[z + 1] - 1 * b[z])
    }
  }

  return(result)
}

computed_Tr <- function(dd, type) {
  day <- c()
  hour <- c()
  Time <- dd$Time
  for (i in seq_len(nrow(dd))) {
    day[i] <- ((lazyopt::fenge(Time[i] %>%
                                 as.character(), " "))[1]) %>%
      as.Date.character() %>%
      as.character()

    hour[i] <- ((lazyopt::fenge(Time[i] %>%
                                  as.character(), " "))[2])
  }

  days <- day
  hours <- hour

  kk <- unique(day) %>%
    sort()
  onedatTimes <- 24 * 60 * 60

  for (i in seq_along(kk)) {
    days[which(day == kk[i])] <- 0 + i * onedatTimes
  }

  for (i in seq_along(hour)) {
    tt <- hour[i] %>%
      as.character() %>%
      lazyopt::fenge() %>%
      as.numeric()

    hours[i] <- tt[1] * 60 * 60 + tt[2] * 60
  }

  days %<>%
    as.numeric()
  hours %<>%
    as.numeric()
  dd %<>%
    mutate(day, hour, days, hours) %>%
    mutate(times = days + hours) %>%
    arrange(times) %>%
    select(1:10)

  Tr <- dd %$% computed_Tr_bytype(Weight, type)

  dd %<>% mutate(Tr)

  return(dd)

}

getdata_unit_genotype <- function(rawData, units, groupData, genotypes,
                                  choose_unit = -1, choose_genotype = -1, opt) {
  if (choose_unit != -1) {
    dd <- get_unit(rawData, choose_unit)
    if (dd != -1) {
      dd %<>%
        computed_vpd_vwc() %>%
        computed_Tr(opt$Tr_computed_type)

      write.table(dd, file = paste0(opt$outputpackage, "/",
                                    choose_unit, ".", "xls"), sep = "\t",
                  col.names = NA)
    }
  }
  if (choose_genotype != -1) {
    dd <- get_genotype(rawData, choose_genotype,
                       genotypes, groupData, units)
    if (dd != -1) {
      dd %<>%
        computed_vpd_vwc() %>%
        computed_Tr(opt$Tr_computed_type)

      write.table(dd, file = paste0(opt$outputpackage, "/",
                                    choose_genotype, ".", "xls"), sep = "\t",
                  col.names = NA)
    }
  }
}


#本机测试参数
arg <- c("-i", "E:/projects/Lysimeter_Systems/src/data/Input.csv",
         "-o", "E:/projects/Lysimeter_Systems/src/output",
         "-g", "E:/projects/Lysimeter_Systems/src/data/plant3.xls",
         "-m", "base", "-cu", "A13")

opt <- matrix(c(
  "inputfile", "i", 2, "character", "Set the input file path", " ",
  "groupfile", "g", 1, "character", "Sets the packet file path", " ",
  "mode", "m", 1, "character", "only two mode,'fool','base',fool mode is for people who are just starting out with scripts", "base",
  "choose_unit", "cu", 1, "character", "canbe split by ':'", "A13",
  "choose_genotype", "cg", 1, "character", "canbe split by ':'", " ",
  "Tr_computed_type", "tct", 1, "character", "three choose [center,forward,Taylor]", "Taylor",
  "outputpackage", "o", 2, "character", "Set the output folder path", " "
), byrow = TRUE, ncol = 6) %>%
  lazyopt(arg = NULL)

rawData <- opt %$%
  read.csv(inputfile)

units <- colnames(rawData)[3:ncol(rawData)]

groupData <- -1

genotypes <- -1

if (opt$groupfile != " ") {
  groupData <- opt %$%
    read.delim(groupfile,
               check.names = FALSE) %>%
    select(c("Name", "#genotype"))
  genotypes <- (groupData[, 2]) %>%
    as.character() %>%
    unique()
}

mode <- opt$mode

#输出以单元或者genotype 的数据
choose_units <- -1

choose_genotypes <- -1

if (mode == "base") {
  choose_units <- opt %$%
    lazyopt::fenge(choose_unit)
  if (choose_units == " ") {
    choose_units <- -1
  }
  if (choose_units == "all") {
    choose_units <- units
  }
  choose_genotypes <- opt %$%
    lazyopt::fenge(choose_genotype)
  if (choose_genotypes == " ") {
    choose_genotypes <- -1
  }
  if (choose_genotypes == "all" &&
    opt$groupfile != " ") {
    choose_genotypes <- genotypes
  }
}

if (mode == "fool") {
  ("  *use fool mode") %>% print()
  print("  *Let's show all units,you can write 'all' to choose all units or add one by one :")
  print(units)
  choose_units <- scan(what = character(), nmax = length(units))
  if (choose_units == "all") {
    choose_units <- units
  }
  if (groupData != -1) {
    print("  *Let's show all genotypes,you can write 'all' to choose all units or add one by one :")
    print(genotypes)
    choose_genotypes <- scan(what = character(),
                             nmax = length(genotypes))
    if (choose_genotypes == "all") {
      choose_genotypes <- genotypes
    }
  }
}


if (choose_units != -1) {
  for (i in seq_along(choose_units)) {
    getdata_unit_genotype(rawData, units, groupData, genotypes,
                          choose_unit = choose_units[i], opt = opt)
  }
}

if (choose_genotypes != -1) {
  for (i in seq_along(choose_genotypes)) {
    getdata_unit_genotype(rawData, units, groupData, genotypes,
                          choose_genotype = choose_genotypes[i], opt = opt)
  }
}












